Hi, Based on Martin Paljak's feedback I have overhauled & extended my patch series for card-openpgp.c
This version of the patch series has been tested for compatibility with a OpenPGP card 1.1: * with my opensc-explorer patches (included into mainline recently by Martin [thank you, BTW]), the card data structures can be explored in detail * pkcs15-crypt can sign hashes passwd to it * remote access with OpenSSH 5.8 works successfully (I do not yet have a encryption key on the card ;-) Please find attached the patch series, which contain extensive description on the top of each file. It would be great if they made it into OpenSC's mainline Thanks Peter -- Peter Marschall pe...@adpm.de
From 5650439ec7362a859855b957203f89538ecf889d Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sat, 26 Mar 2011 17:40:57 +0100 Subject: [PATCH 10/10] OpenPGP: catch calloc() errors in pgp_new_blob() Detect and react on out of memory errors in pgp_new_blob() and its callers. Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 42 +++++++++++++++++++++++++++--------------- 1 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 593087a..4150120 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -83,6 +83,7 @@ struct do_info { int (*put_fn)(sc_card_t *, unsigned int, const u8 *, size_t); }; +static int pgp_finish(sc_card_t *card); static void pgp_iterate_blobs(struct blob *, int, void (*func)()); static struct blob * pgp_new_blob(struct blob *, unsigned int, int, @@ -147,6 +148,7 @@ pgp_init(sc_card_t *card) sc_file_t *file = NULL; struct do_info *info; int r; + struct blob *child; priv = calloc (1, sizeof *priv); if (!priv) @@ -199,14 +201,23 @@ pgp_init(sc_card_t *card) priv->current = priv->mf; - /* Populate MF - add all blobs listed in the pgp_objects - * table. */ + /* Populate MF - add all blobs listed in the pgp_objects table. */ for (info = pgp_objects; info->id > 0; info++) { - pgp_new_blob(priv->mf, info->id, + child = pgp_new_blob(priv->mf, info->id, info->constructed? SC_FILE_TYPE_DF : SC_FILE_TYPE_WORKING_EF, info); + /* catch out of memory condition */ + if (child == NULL) + break; + } + + /* treat out of memory condition */ + if (child == NULL) { + pgp_finish(card); + return SC_ERROR_OUT_OF_MEMORY; } + return SC_SUCCESS; } @@ -260,20 +271,21 @@ pgp_new_blob(struct blob *parent, unsigned int file_id, sc_file_t *file = sc_file_new(); struct blob *blob, **p; - blob = calloc(1, sizeof(*blob)); - blob->parent = parent; - blob->id = file_id; - blob->file = file; - blob->info = info; + if ((blob = calloc(1, sizeof(*blob))) != NULL) { + blob->parent = parent; + blob->id = file_id; + blob->file = file; + blob->info = info; - file->type = file_type; - file->path = parent->file->path; - file->ef_structure = SC_FILE_EF_TRANSPARENT; - sc_append_file_id(&file->path, file_id); + file->type = file_type; + file->path = parent->file->path; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + sc_append_file_id(&file->path, file_id); - for (p = &parent->files; *p; p = &(*p)->next) - ; - *p = blob; + for (p = &parent->files; *p; p = &(*p)->next) + ; + *p = blob; + } return blob; } -- 1.7.4.1
From 101bdb12afd561ef35088ada56c9103d5ed6c677 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 21:41:12 +0100 Subject: [PATCH 01/10] OpenPGP: fix top-level DOs according to spec Added: * 00c4: new top-level DO in 2.0 can also be found inside constructed DOs 006E/0073 in 2.0 & 1.1 * 0101: new optional top-level DO starting in 1.1 for private use max 254 bytes; access: read - always; write - verify CHV2 * 0102: new optional top-level DO starting in 1.1 for private use max 254 bytes; access: read - always; write - verify CHV3 * 0103: new optional top-level DO starting in 1.1 for private use max 254 bytes; access: read - verify CHV2; write - verify CHV2 * 0104: new optional top-level DO starting in 1.1 for private use max 254 bytes; access: read - verify CHV3; write - verify CHV3 * 7f21: new optional top-level DO in 2.0 use: card holder certificate (e.g. X.509) for the AUT key in the card Removed: * 0073: never a top-level DO, but part of top-level constructed DO 006E Changed: * 005e: not a constructed DO, but a simple/primitive DO Note: Trying to read non-existent top-level DOs or top-level DOs that weren't defined in a spec version later than the current card's version does not hurt. They are returned as empty. Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 386e687..de12f48 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -91,12 +91,17 @@ static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, static struct do_info pgp_objects[] = { { 0x004f, 0, 0, sc_get_data, sc_put_data }, - { 0x005e, 1, 0, sc_get_data, sc_put_data }, + { 0x005e, 0, 0, sc_get_data, sc_put_data }, { 0x0065, 1, 0, sc_get_data, sc_put_data }, { 0x006e, 1, 0, sc_get_data, sc_put_data }, - { 0x0073, 1, 0, sc_get_data, sc_put_data }, { 0x007a, 1, 0, sc_get_data, sc_put_data }, + { 0x00c4, 0, 0, sc_get_data, sc_put_data }, + { 0x0101, 0, 0, sc_get_data, sc_put_data }, + { 0x0102, 0, 0, sc_get_data, sc_put_data }, +// { 0x0103, 0, 0, sc_get_data, sc_put_data }, // needs verify with PW1 +// { 0x0104, 0, 0, sc_get_data, sc_put_data }, // needs verify with PW3 { 0x5f50, 0, 0, sc_get_data, sc_put_data }, + { 0x7f21, 1, 0, sc_get_data, sc_put_data }, { 0xb600, 1, 0, pgp_get_pubkey, NULL }, { 0xb800, 1, 0, pgp_get_pubkey, NULL }, { 0xa400, 1, 0, pgp_get_pubkey, NULL }, -- 1.7.4.1
From c81a90eb4563a206557cbdc1261f57f777297ffc Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 18:51:33 +0100 Subject: [PATCH 02/10] OpenPGP: add indication of 2048 RSA agorithm for OpenPGP 2.0 cards Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index de12f48..242774b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -159,6 +159,8 @@ pgp_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 512, flags, 0); _sc_card_add_rsa_alg(card, 768, flags, 0); _sc_card_add_rsa_alg(card, 1024, flags, 0); + if (card->type == SC_CARD_TYPE_OPENPGP_V2) + _sc_card_add_rsa_alg(card, 2048, flags, 0); sc_format_path("D276:0001:2401", &aid); aid.type = SC_PATH_TYPE_DF_NAME; -- 1.7.4.1
From b67a7887386be78d65e10816bcb28e6608c0eaa1 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:04:29 +0100 Subject: [PATCH 03/10] OpenPGP: try to match flags with specification Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 242774b..ec553f9 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -151,8 +151,20 @@ pgp_init(sc_card_t *card) card->cla = 0x00; /* Is this correct? */ + /* OpenPGP card spec 1.1 & 2.0, section 2.1 */ flags = SC_ALGORITHM_RSA_RAW; + /* OpenPGP card spec 1.1 & 2.0, section 7.2.9 & 7.2.10 */ flags |= SC_ALGORITHM_RSA_PAD_PKCS1; + /* OpenPGP card 2.0 spec, section 7.2.8.1 */ + /* + flags |= SC_ALGORITHM_RSA_HASH_SHA1 | + SC_ALGORITHM_RSA_HASH_RIPEMD160; + if (card->type == SC_CARD_TYPE_OPENPGP_V2) + flags |= SC_ALGORITHM_RSA_HASH_SHA224 | + SC_ALGORITHM_RSA_HASH_SHA256 | + SC_ALGORITHM_RSA_HASH_SHA384 | + SC_ALGORITHM_RSA_HASH_SHA512; + */ flags |= SC_ALGORITHM_RSA_HASH_NONE; /* Is this correct? */ -- 1.7.4.1
From 698bb34eaf63f4529ce054e7d18a669adc4d314f Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sat, 19 Mar 2011 21:28:49 +0100 Subject: [PATCH 04/10] OpenPGP: re-factor pgp_enumerate_blob() Leverage the fact that OpenPGP cards use TLV encoding according to ASN.1 BER-encoding rules and use sc_asn1_read_tag() as the workhorse within pgp_enumerate_blob(). There's one peculiarity though: OpenPGP cards expect 'cla' to be merged into 'tag'. This is done manually after calling sc_asn1_read_tag(). Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 66 +++++++++++++++++------------------------ 1 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index ec553f9..3f63376 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -277,12 +277,12 @@ pgp_read_blob(sc_card_t *card, struct blob *blob) /* * Enumerate contents of a data blob. - * The OpenPGP card has a funny TLV encoding. + * The OpenPGP card has a TLV encoding according ASN.1 BER-encoding rules. */ static int pgp_enumerate_blob(sc_card_t *card, struct blob *blob) { - const u8 *in, *end; + const u8 *in; int r; if (blob->files != NULL) @@ -292,52 +292,40 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob) return r; in = blob->data; - end = blob->data + blob->len; - while (in < end) { - unsigned int tag, len, type = SC_FILE_TYPE_WORKING_EF; - unsigned char c; - c = *in++; - if (c == 0x00 || c == 0xFF) - continue; + while (blob->len > (in - blob->data)) { + unsigned int cla, tag, tmptag; + unsigned int type = SC_FILE_TYPE_WORKING_EF; + size_t len; + u8 *data = in; + struct blob *new; - tag = c; - if (tag & 0x20) - type = SC_FILE_TYPE_DF; - while ((c & 0x1f) == 0x1f) { - if (in >= end) - goto eoc; - c = *in++; - tag = (tag << 8) | c; + r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), + &cla, &tag, &len); + if (r < 0) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "Unexpected end of contents\n"); + return SC_ERROR_OBJECT_NOT_VALID; } - if (in >= end) - goto eoc; - c = *in++; - if (c < 0x80) { - len = c; - } else { - len = 0; - c &= 0x7F; - while (c--) { - if (in >= end) - goto eoc; - len = (len << 8) | *in++; - } - } + /* create fake file system hierarchy by + * using constructed DOs as DF */ + if (cla & SC_ASN1_TAG_CONSTRUCTED) + type = SC_FILE_TYPE_DF; - /* Don't search past end of content */ - if (in + len > end) - goto eoc; + /* undo ASN1's split of tag & class */ + for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) { + cla <<= 8; + } + tag |= cla; - pgp_set_blob(pgp_new_blob(blob, tag, type, NULL), in, len); - in += len; + if ((new = pgp_new_blob(blob, tag, type, NULL)) == NULL) + return SC_ERROR_OUT_OF_MEMORY; + pgp_set_blob(new, data, len); + in = data + len; } return 0; - -eoc: sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unexpected end of contents\n"); - return SC_ERROR_OBJECT_NOT_VALID; } static int -- 1.7.4.1
From 79aa1d41dc482462439c8418e0e1141746ea0b47 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:26:35 +0100 Subject: [PATCH 07/10] OpenPGP: re-factor pgp_set_blob() * NULL-ify freed data pointer * avoid unnecessary malloc() calls * cope with malloc() errors * do not rely on blob->file for be set Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 20 ++++++++++++++++---- 1 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index c40c004..2883193 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -231,12 +231,24 @@ pgp_set_blob(struct blob *blob, const u8 *data, size_t len) { if (blob->data) free(blob->data); - blob->len = len; + blob->data = NULL; + blob->len = 0; blob->status = 0; - blob->data = malloc(len); - memcpy(blob->data, data, len); - blob->file->size = len; + if (len > 0) { + void *tmp = malloc(len); + + if (tmp == NULL) + return SC_ERROR_OUT_OF_MEMORY; + + blob->data = tmp; + blob->len = len; + memcpy(blob->data, data, len); + } + + if (blob->file) + blob->file->size = len; + return 0; } -- 1.7.4.1
From 50d2ac8184c76cc4f56193904e24bb171cc42755 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sat, 19 Mar 2011 20:06:42 +0100 Subject: [PATCH 05/10] OpenPGP: implement function to free the fake file system * pgp_iterate_blobs(): walk through the blob tree * pgp_free_blob(): free a blob Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 57 ++++++++++++++++++++++++++++++++++++------ 1 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3f63376..f21d5fb 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -82,8 +82,11 @@ struct do_info { int (*put_fn)(sc_card_t *, unsigned int, const u8 *, size_t); }; +static void pgp_iterate_blobs(struct blob *, int, void (*func)()); + static struct blob * pgp_new_blob(struct blob *, unsigned int, int, struct do_info *); +static void pgp_free_blob(struct blob *); static int pgp_get_pubkey(sc_card_t *, unsigned int, u8 *, size_t); static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, @@ -114,7 +117,7 @@ static struct do_info pgp_objects[] = { #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) struct pgp_priv_data { - struct blob mf; + struct blob * mf; struct blob * current; sc_security_env_t sec_env; @@ -147,6 +150,12 @@ pgp_init(sc_card_t *card) priv = calloc (1, sizeof *priv); if (!priv) return SC_ERROR_OUT_OF_MEMORY; + priv->mf = calloc(1, sizeof(struct blob)); + if (!priv->mf) { + free(priv); + return SC_ERROR_OUT_OF_MEMORY; + } + card->drv_data = priv; card->cla = 0x00; @@ -184,15 +193,15 @@ pgp_init(sc_card_t *card) file->type = SC_FILE_TYPE_DF; file->id = 0x3f00; - priv->mf.file = file; - priv->mf.id = 0x3F00; + priv->mf->file = file; + priv->mf->id = 0x3F00; - priv->current = &priv->mf; + priv->current = priv->mf; /* Populate MF - add all blobs listed in the pgp_objects * table. */ for (info = pgp_objects; info->id > 0; info++) { - pgp_new_blob(&priv->mf, info->id, + pgp_new_blob(priv->mf, info->id, info->constructed? SC_FILE_TYPE_DF : SC_FILE_TYPE_WORKING_EF, info); @@ -209,7 +218,8 @@ pgp_finish(sc_card_t *card) return 0; priv = DRVDATA (card); - /* XXX delete fake file hierarchy */ + /* delete fake file hierarchy */ + pgp_iterate_blobs(priv->mf, 99, pgp_free_blob); free(priv); return 0; @@ -254,6 +264,37 @@ pgp_new_blob(struct blob *parent, unsigned int file_id, return blob; } +static void +pgp_free_blob(struct blob *blob) +{ + if (blob) { + if (blob->file) + sc_file_free(blob->file); + if (blob->data) + free(blob->data); + free(blob); + } +} + + +static void +pgp_iterate_blobs(struct blob *blob, int level, void (*func)()) +{ + if (blob) { + if (level > 0) { + struct blob *child = blob->files; + + while (child != NULL) { + struct blob *next = child->next; + + pgp_iterate_blobs(child, level-1, func); + child = next; + } + } + func(blob); + } +} + static int pgp_read_blob(sc_card_t *card, struct blob *blob) { @@ -375,7 +416,7 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) path = &path_copy; } - blob = &priv->mf; + blob = priv->mf; for (n = 0; n < path->len; n += 2) { r = pgp_get_blob(card, blob, (path->value[n] << 8) | path->value[n+1], @@ -492,7 +533,7 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called, tag=%04x\n", tag); - if ((r = pgp_get_blob(card, &priv->mf, tag & 0xFFFE, &blob)) < 0 + if ((r = pgp_get_blob(card, priv->mf, tag & 0xFFFE, &blob)) < 0 || (r = pgp_get_blob(card, blob, 0x7F49, &blob)) < 0 || (r = pgp_get_blob(card, blob, 0x0081, &mod_blob)) < 0 || (r = pgp_get_blob(card, blob, 0x0082, &exp_blob)) < 0 -- 1.7.4.1
From 15ef4432ab38deceb85fcbfec763033975c21b77 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:08:16 +0100 Subject: [PATCH 06/10] OpenPGP: NULL-ify free()'d pointer Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index f21d5fb..c40c004 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -222,6 +222,7 @@ pgp_finish(sc_card_t *card) pgp_iterate_blobs(priv->mf, 99, pgp_free_blob); free(priv); + card->drv_data = NULL; return 0; } -- 1.7.4.1
From 10ad8faed1700d3ce7146fca2ecb72e75ac1cbf8 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:32:05 +0100 Subject: [PATCH 08/10] OpenPGP: add some comments Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 2883193..ebf9377 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -61,8 +61,8 @@ static struct sc_card_driver pgp_drv = { * Everything else is mapped to "file" IDs. */ struct blob { - struct blob * next; - struct blob * parent; + struct blob * next; /* pointer to next sibling */ + struct blob * parent; /* pointer to parent */ struct do_info *info; sc_file_t * file; @@ -71,7 +71,7 @@ struct blob { unsigned char * data; unsigned int len; - struct blob * files; + struct blob * files; /* pointer to 1st child */ }; struct do_info { -- 1.7.4.1
From 38f330041d2f4c2ed9c275054615ed8384504170 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Thu, 24 Mar 2011 08:57:31 +0100 Subject: [PATCH 09/10] OpenPGP: use symbolic names for errors/success Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 23 ++++++++++++----------- 1 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index ebf9377..593087a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -33,6 +33,7 @@ #include "internal.h" #include "asn1.h" #include "cardctl.h" +#include "errors.h" static struct sc_atr_table pgp_atrs[] = { { "3b:fa:13:00:ff:81:31:80:45:00:31:c1:73:c0:01:00:00:90:00:b1", NULL, "OpenPGP card v1.0/1.1", SC_CARD_TYPE_OPENPGP_V1, 0, NULL }, @@ -206,7 +207,7 @@ pgp_init(sc_card_t *card) : SC_FILE_TYPE_WORKING_EF, info); } - return 0; + return SC_SUCCESS; } static int @@ -215,7 +216,7 @@ pgp_finish(sc_card_t *card) struct pgp_priv_data *priv; if (card == NULL) - return 0; + return SC_SUCCESS; priv = DRVDATA (card); /* delete fake file hierarchy */ @@ -223,7 +224,7 @@ pgp_finish(sc_card_t *card) free(priv); card->drv_data = NULL; - return 0; + return SC_SUCCESS; } static int @@ -249,7 +250,7 @@ pgp_set_blob(struct blob *blob, const u8 *data, size_t len) if (blob->file) blob->file->size = len; - return 0; + return SC_SUCCESS; } static struct blob * @@ -315,13 +316,13 @@ pgp_read_blob(sc_card_t *card, struct blob *blob) int r; if (blob->data != NULL) - return 0; + return SC_SUCCESS; if (blob->info == NULL) return blob->status; r = blob->info->get_fn(card, blob->id, buffer, sizeof(buffer)); - if (r < 0) { + if (r < 0) { /* an error occurred */ blob->status = r; return r; } @@ -340,7 +341,7 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob) int r; if (blob->files != NULL) - return 0; + return SC_SUCCESS; if ((r = pgp_read_blob(card, blob)) < 0) return r; @@ -379,7 +380,7 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob) in = data + len; } - return 0; + return SC_SUCCESS; } static int @@ -400,7 +401,7 @@ pgp_get_blob(sc_card_t *card, struct blob *blob, unsigned int id, if (child != NULL) { (void) pgp_read_blob(card, child); *ret = child; - return 0; + return SC_SUCCESS; } return SC_ERROR_FILE_NOT_FOUND; @@ -444,7 +445,7 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) if (ret) sc_file_dup(ret, blob->file); - return 0; + return SC_SUCCESS; } static int @@ -647,7 +648,7 @@ pgp_set_security_env(sc_card_t *card, } priv->sec_env = *env; - return 0; + return SC_SUCCESS; } static int -- 1.7.4.1
_______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel