Hi, this is my first post to the list, so please bear with me, if I do not follow the "standard procedure" for sending in patches.
Please find attached a few patches to src/libopensc/card-openpgp.c * 0001-OpenPGP-fix-top-level-DOs-according-to-spec.patch align the list of top-level data objects with the spec * 0002-OpenPGP-add-indication-of-2048-RSA-agorithm-for-Open.patch indicate 2048-bit support for version 2.0 cards * 0003-OpenPGP-try-to-match-flags-with-specification.patch get algorithm flags from the spec (commented out) * 0004-OpenPGP-according-to-spec-DO-5E-is-not-constructed.patch additional fix to align top-level data objects with the spec * 0005-OpenPGP-document-TLV-encoding-use-symbolic-values.patch add comments to document the "funny TLV" encoding * 0006-OpenPGP-implement-function-to-free-the-fake-file-sys.patch free the fake file hierarchy created during run time * 0007-OpenPGP-NULL-ify-free-d-pointer.patch set a free'd pointer to NULL * 0008-OpenPGP-only-malloc-when-we-need-to.patch avoid an unnecessary malloc(0) * 0009-OpenPGP-add-some-comments.patch a few more comments It would be cool if you included them into OpenSC mainstream Best regards Peter -- Peter Marschall pe...@adpm.de
From d5667b06dec42be7c92b3aafff28a5ce4d24f792 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:32:05 +0100 Subject: [PATCH 9/9] 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 53a89c9..1c7a416 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 acc0137ef938bb4a0cd9debfeeace35941b9d005 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:26:35 +0100 Subject: [PATCH 8/9] OpenPGP: only malloc() when we need to Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 72defed..53a89c9 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -234,8 +234,11 @@ pgp_set_blob(struct blob *blob, const u8 *data, size_t len) free(blob->data); blob->len = len; blob->status = 0; - blob->data = malloc(len); - memcpy(blob->data, data, len); + blob->data = NULL; + if (len > 0) { + blob->data = malloc(len); + memcpy(blob->data, data, len); + } blob->file->size = len; return 0; -- 1.7.4.1
From 692b4bb21bb90c77e6dc8fc81ea1248eaceaa32c Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sat, 19 Mar 2011 20:06:42 +0100 Subject: [PATCH 6/9] 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 5f0e43b..bb80b7f 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, @@ -115,7 +118,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; @@ -148,6 +151,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; @@ -185,15 +194,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); @@ -210,7 +219,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; @@ -255,6 +265,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) { @@ -412,7 +453,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], @@ -529,7 +570,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 1cbd289d8fa13aecf7bda9cb6db8291b8a4055fa Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sat, 19 Mar 2011 21:28:49 +0100 Subject: [PATCH 5/9] OpenPGP: document TLV encoding, use symbolic values Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 34 +++++++++++++++++++++++++++++----- 1 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index c3bf31e..5f0e43b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -278,7 +278,7 @@ 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) @@ -299,13 +299,30 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob) unsigned char c; c = *in++; + + /* tag values 00 and FF are forbidden */ if (c == 0x00 || c == 0xFF) continue; tag = c; - if (tag & 0x20) + /* tag flags: + * tag & 0xD0 = 0x00: universal class + * tag & 0xD0 = 0x40: application class + * tag & 0xD0 = 0x80: context specific class + * tag & 0xD0 = 0xC0: private class + * tag & 0x20 = 0x00: simple/primitive data object + * tag & 0x20 = 0x20: constructed data object + * tag & 0x1F < 0x1F: tag ID + * tag & 0x1F = 0x1F: next byte belongs to tag + */ + + /* fake file system hierarchy by + * treating constructed DOs as DF */ + if (tag & SC_ASN1_TAG_CONSTRUCTED) type = SC_FILE_TYPE_DF; - while ((c & 0x1f) == 0x1f) { + + /* two byte tag */ + while ((c & SC_ASN1_TAG_PRIMITIVE) == SC_ASN1_TAG_ESCAPE_MARKER) { if (in >= end) goto eoc; c = *in++; @@ -315,10 +332,17 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob) if (in >= end) goto eoc; c = *in++; + + /* length: may have 1 to 3 bytes: + * 1st byte < 0x80: 1-byte length; 0 - 127 + * 1st byte = 0x81: 2-byte length; 0 - 255 + * 1st byte = 0x82: 3-byte length; 0 - 65535 + */ + if (c < 0x80) { - len = c; + len = c; /* 1-byte length */ } else { - len = 0; + len = 0; /* 2- or 3-byte length */ c &= 0x7F; while (c--) { if (in >= end) -- 1.7.4.1
From cd42b7a01385ad9b9280211034337c8d6f358653 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:11:24 +0100 Subject: [PATCH 4/9] OpenPGP: according to spec, DO 5E is not constructed Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5a1fd7c..c3bf31e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -91,7 +91,7 @@ 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 }, // part of 006E -- 1.7.4.1
From cbc000c7e30df1d973b45eef7c7461c4f56d22a6 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 18:51:33 +0100 Subject: [PATCH 2/9] 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 058b62e..cc88cbc 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -160,6 +160,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 0382c005807f185fdf4e2df429653d07d5df7913 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 21:41:12 +0100 Subject: [PATCH 1/9] OpenPGP: fix top-level DOs according to spec Signed-off-by: Peter Marschall <pe...@adpm.de> --- src/libopensc/card-openpgp.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 386e687..058b62e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -94,9 +94,15 @@ static struct do_info pgp_objects[] = { { 0x005e, 1, 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 }, +// { 0x0073, 1, 0, sc_get_data, sc_put_data }, // part of 006E { 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 041ebd8cde8e65753edb3e8edbf86200fabdabfa Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:04:29 +0100 Subject: [PATCH 3/9] 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 cc88cbc..5a1fd7c 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -152,8 +152,20 @@ pgp_init(sc_card_t *card) card->cla = 0x00; /* Is this correct? */ + /* OpenPGP card 2.0 spec, section 2.1 */ flags = SC_ALGORITHM_RSA_RAW; + /* OpenPGP card 2.0 spec, 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 fa81d185af914757ccb65e31deef9c39ec499718 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 13 Mar 2011 19:08:16 +0100 Subject: [PATCH 7/9] 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 bb80b7f..72defed 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -223,6 +223,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
_______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel